package com.ss.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.ss.domain.Student;
import com.ss.mapper.StudentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class StudentListener implements ReadListener<Student> {
    @Autowired
    StudentMapper studentMapper;

    private ArrayList<Student> students = new ArrayList<>();
    private ThreadLocal<ArrayList<Student>> studentsThreadLocal = ThreadLocal.withInitial(ArrayList::new);
    private static final int batchSize = 10000;
    private static AtomicInteger count = new AtomicInteger(1);

    @Override
    public void invoke(Student student, AnalysisContext analysisContext) {
        // 单条插入
//        saveOne(student);

        // 批量插入
//        students.add(student);
//        if(students.size() >= batchSize){
//            saveData();
//        }

        // 批量插入
        studentsThreadLocal.get().add(student);
        if(studentsThreadLocal.get().size() >= batchSize){
            saveDataAsync();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveDataAsync(); // 解决了每个sheet最后一批数据条数不足batchsize时不触发写入
        System.out.println("一个sheet全部解析完毕");
        studentsThreadLocal.get().clear(); // 解决程序不停止读取下一个文件后，会解析内存中遗留数据
    }

    private void saveOne(Student student){
        studentMapper.insertStudent(student);
        System.out.println("第" + count.getAndAdd(1) + "次插入1条数据");
    }

    private void saveData(){
        if(!students.isEmpty()){
            studentMapper.insertStudents(students);
            System.out.println("第" + count.getAndAdd(1) + "次插入" + students.size() + "条数据");
            students.clear();
        }
    }

    private void saveDataAsync(){
        if(!studentsThreadLocal.get().isEmpty()){
            studentMapper.insertStudents(studentsThreadLocal.get());
            System.out.println("第" + count.getAndAdd(1) + "次插入" + studentsThreadLocal.get().size() + "条数据");
            studentsThreadLocal.get().clear();
        }
    }
}
